Учебный курс: Подготовка на 1С:Специалист по платформе 1С:Предприятие 8.3

Задачи по расчетным механизмам – тема № 6:
Что такое механизм вытеснения и как он используется при расчете периодических начислений

В данном блоке используются материалы, которые были рассмотрены ранее:

Практически во всех задачах по расчетным механизмам присутствует часть, в которой требуется использовать механизм вытеснения. Например, такие виды расчета, как больничный, командировка, отпуск или прогул не должны начисляться вместе с окладом, а должны его вытеснять по периоду действия. Этот механизм используется во многих задачах, например 3.1, 3.2, 3.3 и др.

Рассмотрим механизм вытеснения на примере решения одной из аттестационных задач. Так как в условии данной задачи встречаются сложные формулировки, мы вынуждены процитировать билет с аттестации. Текст билета предоставлен нам читателем, сдававшим экзамен, поэтому цитата может быть неточной. Формулировки билетов также могут меняться компанией “1С”.

«Сотрудники предприятия получают оплату по окладу пропорционально отработанному времени в часах. Сумма начисления по окладу определяется как начальное значение оклада, деленное на количество рабочих часов в том же периоде, что и фактически отработанные часы. В случае невыхода сотрудника на работу без уважительной причины ему регистрируется Прогул, и в этом случае начисление по окладу не происходит. Все сотрудники работают по пятидневному графику работы, однако в решении необходимо предусмотреть возможность работы по нескольким различным графикам.»

Для начала определимся с условиями задачи, например, что означает формулировка «Сумма начисления по окладу определяется как начальное значение оклада, деленное на количество рабочих часов в том же периоде, что и фактически отработанные часы».

Под периодом, который совпадает с фактически отработанными и рабочими часами (норма часов), здесь понимается период действия начисления (оклада), а не регистрации, потому что период действия подразумевает интервал рабочего времени, когда сотрудник выполнял работу, а не когда это начисление было зарегистрировано. В данном примере оклад может быть зарегистрирован и в следующем месяце по отношению к периоду, когда работы были действительно выполнены, например, по «забывчивости» бухгалтера, не посчитавшего зарплату вовремя.

Для решения задачи будем использовать план видов расчета ОсновныеНачисления, который уже присутствует в каркасной конфигурации.

План видов расчета ОсновныеНачисления

Рисунок 1 – План видов расчета ОсновныеНачисления

Включим для него параметр Использует период действия, чтобы задействовать механизм вытеснения, а параметр Зависимость от базы поставим в значение Не зависит, т.к. в данном примере получение базы не требуется.

Закладка Расчет Плана видов расчета ОсновныеНачисления

Рисунок 2 – Закладка Расчет Плана видов расчета ОсновныеНачисления

Параметр Использует период действия для плана видов расчета ОсновныеНачисления включили, потому что в тексте задачи написано, что виды расчета Оклад и Прогул являются взаимоисключающими и поэтому не могут быть начислены за один и тот же период.

Перейдем на закладку Прочее и откроем список предопределенных элементов видов расчета.

Закладка Прочее Плана видов расчета ОсновныеНачисления

Рисунок 3 – Закладка Прочее Плана видов расчета ОсновныеНачисления

Добавим предопределенный вид расчета Прогул.

Добавление вида расчета Прогул

Рисунок 4 – Добавление вида расчета Прогул

Для оклада будем использовать существующий предопределенный вид расчета Оклад.

Добавление вида расчета Оклад

Рисунок 5 – Вид расчета Оклад

Для вида расчета Окладв табличной части Вытесняющие отметим флажком вид расчета Прогул:

Настройка вытеснения для вида расчета Оклад

Рисунок 6 – Настройка вытеснения для вида расчета Оклад

Следующим шагом будет настройка регистра сведений с графиками работ.

Несмотря на то, что по условию задачи все сотрудники работают по пятидневному графику работы, в задаче есть важное уточнение: «в решении необходимо предусмотреть возможность работы по нескольким различным графикам». Поэтому добавим в конфигурацию простейший справочник без реквизитов ГрафикиРаботы.

Справочник ГрафикиРаботы

Рисунок 7 – Справочник ГрафикиРаботы

Для регистра сведений ГрафикиРаботы, который уже присутствует в каркасной конфигурации, добавим измерение ГрафикРаботы, которое будет ссылаться на справочник ГрафикиРаботы.

В данном случае для пятидневки это будет по 8 ч. с понедельника по пятницу, а в выходные, соответственно, 0 ч.

Структура регистра сведений ГрафикиРаботы

Рисунок 8 – Структура регистра сведений ГрафикиРаботы

Вручную заполнять регистр сведений будет долго, поэтому для этих целей используется обработка, которая входит в состав каркасной конфигурации и называется Заполнение графика:

Обработка ЗаполнениеГрафика

Рисунок 9 – Обработка ЗаполнениеГрафика

Выполним минимальные доработки обработки для заполнения регистра сведений ГрафикиРаботы с учетом добавленного измерения ГрафикРаботы.

Добавим реквизит формы ГрафикРаботы и выведем его на форму.

Добавление графика работы в обработку ЗаполнениеГрафика

Рисунок 10 – Добавление графика работы в обработку ЗаполнениеГрафика

В модуле формы скорректируем процедуру ВыполнитьОбработку().

Передадим в качестве параметра ГрафикРаботы.

Добавление параметра ГрафикРаботы в вызове процедуры

Рисунок 11 – Добавление параметра ГрафикРаботы в вызове процедуры

В модуле объекта обработки скорректируем процедуру ЗаполнитьГрафик().

В начале процедуры скорректируем список параметров и установим отбор по графику работы у набора записей.

Добавление параметра ГрафикРаботы в процедуру ЗаполнитьГрафик

Рисунок 12 – Добавление параметра ГрафикРаботы в процедуру ЗаполнитьГрафик

Заполним у записи набора записей измерение ГрафикРаботы.

Заполнение в записи регистра измерения ГрафикРаботы

Рисунок 13 – Заполнение в записи регистра измерения ГрафикРаботы

Далее создадим регистр расчета, который назовем ОсновныеНачисления и включим для него признак Период действия, а вот признак Базовый период мы оставим выключенным. Для созданного регистра на вкладке Основные укажем одноименный план видов расчета.

Указание ПВР для регистра расчета

Рисунок 14 – Указание ПВР для регистра расчета

Затем свяжем регистр расчета с регистром сведений ГрафикиРабот, созданным на предыдущем шаге. Для этого заполним следующие настройки:

  • График – ГрафикиРаботы
  • Значение графика – Значение
  • Дата графика – Дата

Настройка регистра расчета для связи с графиком работ

Рисунок 15 – Настройка регистра расчета для связи с графиком работ

Перейдем на закладку Данные и добавим:

  • измерение Сотрудник (Справочник ФизическиеЛица)
  • ресурс Результат (Число 10, 2)
  • реквизит Размер (Число 10, 2), в котором будем сохранять начальное значение оклада для расчета.
  • реквизит ГрафикРаботы (Справочник ГрафикиРаботы).

Структура регистра расчета ОсновныеНачисления

Рисунок 16 – Структура регистра расчета ОсновныеНачисления

Свяжем реквизит ГрафикРаботы с соответствующим измерением регистра сведений ГрафикиРабот.

Настройка связи реквизита ГрафикРаботы с измерением регистра сведений ГрафикиРабот

Рисунок 17 – Настройка связи реквизита ГрафикРаботы с измерением регистра сведений ГрафикиРабот

Почему мы создали именно реквизит ГрафикРаботы, а не измерение, подробно рассказано в блоке «4. Настройки регистра расчета, на которые нужно обратить внимание при решении аттестационного задания». Для задач, где нужно использовать несколько графиков, теперь имеем возможность в режиме «1С Предприятия» для каждой записи регистра указать свой график работы. Но в нашей задаче этого не требуется, поэтому будем везде указывать один график работы Пятидневка.

Регистратором данного регистра будет документ «Начисление зарплаты», который будет делать движения по регистру расчета на основе табличной части документа ОсновныеНачисления, при этом ПериодРегистрации будет заполнен по одноименному реквизиту шапки документа.

Закладка Регистраторы регистра расчета ОсновныеНачисления

Рисунок 18 – Закладка Регистраторы регистра расчета ОсновныеНачисления

Теперь при проведении документа «Начисление зарплаты», в случае пересечении периодов действия по видам расчета Оклад и Прогул, будет задействован механизм вытеснения:

Определение фактического периода действия с учетом механизма вытеснения

Рисунок 19 – Определение фактического периода действия с учетом механизма вытеснения

На следующем шаге скорректируем структуру документа «Начисление зарплаты». Добавим реквизиты:

  •  ПериодРегистрации (Дата)
  •  в табличную часть ОсновныеНачисления:
    • ГрафикРаботы (Справочник ГрафикиРаботы)

Документ НачислениеЗарплаты

Рисунок 20 – Документ НачислениеЗарплаты

Следует отметить, что для начисления заработной платы оперативное проведение не нужно, поэтому соответствующее свойство документа должно быть установлено в Запретить:

Настройка документа для отключения оперативного проведения

Рисунок 21 – Настройка документа для отключения оперативного проведения

Откроем модуль документа НачислениеЗарплаты и создадим процедуру ОбработкаПроведения.

В обработке проведения документа «Начисление зарплаты» запишем движения и выполним расчет записей, вызвав процедуру Рассчитать.

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
	
	// 1. Установка маркера Записи у регистра 
	Движения.ОсновныеНачисления.Записывать = Истина;
	
	
	// 2. Движения по регистру
	Для каждого СтрокаТЧ Из ОсновныеНачисления Цикл
		Запись = Движения.ОсновныеНачисления.Добавить();
		ЗаполнитьЗначенияСвойств(Запись, СтрокаТЧ);
		Запись.ПериодРегистрации = ПериодРегистрации;
		Запись.ПериодДействияНачало = СтрокаТЧ.ДатаНачала; 
		Запись.ПериодДействияКонец = КонецДня(СтрокаТЧ.ДатаОкончания);
	КонецЦикла;
	
	// 3. Запись движений документа до выполнения расчетов	
	Движения.Записать();
	
	// 4. Выполнение расчетов
	ПроведениеРасчетов.Рассчитать(Движения.ОсновныеНачисления, Ссылка);
	
КонецПроцедуры

Рассмотрим ключевые точки алгоритма.

Установка маркера Записи у регистра (п.1)

Установим маркер Записывать в значение Истина, чтобы при использовании метода Движения.Записать() записались движения по регистру расчета «Основные начисления».

Движения по регистру (п.2)

В цикле обойдем табличную часть документа и сформируем движения по регистру расчета «Основные начисления».

Запись движений документа до выполнения расчетов (п.3)

Запись набора перед расчетом необходима для того, чтобы было учтено влияние записей регистра расчета друг на друга, т.к. будет задействован механизм вытеснения. За счет этого фактический период действия некоторых записей может быть уменьшен, например, если Оклад будет вытеснен записью с видом расчета Прогул.

Выполнение расчетов (п.4)

Для расчета создадим серверный общий модуль ПроведениеРасчетов и в нем опишем экспортную процедуру Рассчитать с параметрами НаборЗаписей и Регистратор, а в ней опишем алгоритм расчета.

Расчетную часть рекомендуется выносить в отдельный общий модуль, т.к. этот функционал может использоваться в различных документах, например «Отпуск», «Больничный» и др.

Рассмотрим процедуру Рассчитать.

Процедура Рассчитать(НаборЗаписей, Регистратор) Экспорт
    // 1. Запрос, в котором получается факт и норма часов рабочего времени
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    ДанныеГрафика.НомерСтроки,
    |    ДанныеГрафика.ВидРасчета,
    |    ЕстьNULL(ДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК ОтработаноЧасов,
    |    ЕстьNULL(ДанныеГрафика.ЗначениеПериодДействия, 0) КАК НормаЧасов
    |ИЗ
    |    РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(Регистратор = &Регистратор) КАК ДанныеГрафика";
        
    Запрос.УстановитьПараметр("Регистратор", Регистратор);
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    // 2. Определение структуры для поиска по номеру строки
    ПоляПоиска = Новый Структура("НомерСтроки");
        
    Для Каждого Запись Из НаборЗаписей Цикл
    
	ПоляПоиска.НомерСтроки = Запись.НомерСтроки;
        
	// 3. Поиск нужной строки выборки по номеру строки записи
	Если Выборка.НайтиСледующий(ПоляПоиска) Тогда
            
		ВидРасчета = Выборка.ВидРасчета;
        
		Если ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Оклад Тогда
                
			Запись.Результат = ?(Выборка.НормаЧасов = 0, 0, Запись.Размер * Выборка.ОтработаноЧасов / Выборка.НормаЧасов);
                
		ИначеЕсли ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Прогул Тогда
                
			Запись.Результат = 0;
                
		КонецЕсли; 
        
	КонецЕсли; 
        
	//4. Позицию выборки необходимо сбросить в начало
	Выборка.Сбросить();
    
    КонецЦикла; 
    
    //5. Запись набора без пересчета фактического периода действия
    НаборЗаписей.Записать(,, Ложь);

КонецПроцедуры

Рассмотрим ключевые точки алгоритма.

Запрос (п.1)

Получим факт и норму часов рабочего времени из виртуальной таблицы ДанныеГрафика регистра расчета ОсновныеНачисления. Поля для получения количества часов здесь приводятся к нулю с помощью функции ЕСТЬNULL на случай, если регистр сведений с графиками работ не заполнен.

Расчет результата (п.2, п.3, п.4)

Создадим структуру для поиска записей в выборке по номеру строки. В цикле обойдем набор записей и на каждом шаге будем заполнять поле для поиска записи. Если запись найдена, в зависимости от вида расчета выполним расчет результата.

Запись набора без пересчета фактического периода действия (п.5)

Записываем набор записей без пересчета фактического периода действия, т.к. он рассчитан ранее в обработке проведения документа при предварительной записи данных табличной части в регистр. А в этой процедуре мы никак не влияем на период действия записей и не меняем их состав, поэтому для увеличения производительности записи документа пересчет фактического периода действия опускаем, указав третий параметр Ложь в процедуре Записать.

Запустим конфигурацию в режиме «1С:Предприятие» и проверим выполненные доработки.

Добавим график работы Пятидневка и заполним его с помощью обработки Заполнение графика.

Заполнение графика работы

Рисунок 22 – Заполнение графика работы

Введем тестовые данные в документ и проведем его.

Пользовательские данные документа «Начисление зарплаты»

Рисунок 23 – Пользовательские данные документа «Начисление зарплаты»

Проверим корректность расчетов для записей регистра расчета. В марте всего 168 рабочих часов, прогул составил 24 часа, т.е. сотрудник фактически отработал 144 часа. Рассчитаем результат:

50 000 * 144/168 = 42 857,14

Рассчитанная сумма равна значению в регистре Основные начисления.

Движения документа «Начисление зарплаты»

Рисунок 24 – Движения документа «Начисление зарплаты»

В данном примере рассмотрен прием решения подзадачи, которая практически всегда присутствует в том или другом виде в аттестационных задачах по расчетным механизмам. На практическом примере были рассмотрены планы видов расчета и регистры расчета в части настройки механизма вытеснения, а также различные особенности и нюансы, позволяющие избежать ошибок при их настройке.

Перейти к следующей теме:
“Как выполнить настройки для получения базы при расчете премии” (№ 7)

Комментарии закрыты